package com.rose.datax.dataxadmin.action;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rose.datax.dataxadmin.action.request.MaskRequest;
import com.rose.datax.dataxadmin.action.request.TaskRequest;
import com.rose.datax.dataxadmin.entity.*;
import com.rose.datax.dataxadmin.manager.DatabaseViewerMng;
import com.rose.datax.dataxadmin.manager.JobFileGenerator;
import com.rose.datax.dataxadmin.mapper.MigrationTableMapper;
import com.rose.datax.dataxadmin.mapper.MigrationTaskMapper;
import com.rose.datax.dataxadmin.mapper.TransformerMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.configurationprocessor.json.JSONArray;
import org.springframework.boot.configurationprocessor.json.JSONObject;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Controller
@Slf4j
public class TaskAction extends BaseAction {

    @Resource
    private DatabaseViewerMng viewerMng;

    @Resource
    private MigrationTaskMapper taskMapper;
    @Resource
    private MigrationTableMapper tableMapper;

    @Resource
    private TransformerMapper transformerMapper;

    @Resource
    private JobFileGenerator jobFileGenerator;

    @Resource
    private StringRedisTemplate template;

    @GetMapping(value="/tasks",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public Response tasks(){
        Page<MigrationTask> page = getPage();
        IPage<MigrationTask> pages = taskMapper.query(page);
        Response response = new Response();
        response.setTotal(pages.getTotal());
        response.setItems(pages.getRecords());
        return response;
    }

    @RequestMapping(value = "/task/tables", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public Response getTables(Long sourceId, String database){
        Response response = new Response();
        List<DataTable> tables = viewerMng.getSourceTables(sourceId, database);
        response.setItems(tables);
        response.setTotal(tables.size());
        return response;
    }

    @RequestMapping(value = "/task/{taskId}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public JSONResult delete(@PathVariable long taskId){
        taskMapper.deleteById(taskId);
        tableMapper.delete(new QueryWrapper<MigrationTable>().eq("task_id",taskId));
        return new JSONResult();
    }

    @RequestMapping(value = "/task", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public JSONResult createTask(@RequestBody TaskRequest request){
        MigrationTask task = request.convert(MigrationTask.class);
        task.setTables(request.getTables().length);
        taskMapper.insert(task);

        List<MigrationTable> tables = new ArrayList<>();
        MigrationTable table = null;
        for(String tableName: request.getTables()){
            table = new MigrationTable();
            table.setTaskId(task.getId());
            table.setTableName(tableName);
            tables.add(table);
        }
        if(tables.size() > 0) {
            tableMapper.addBatch(tables);
        }
        return new JSONResult();
    }

    @RequestMapping(value = "/task/run/{taskId}", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public JSONResult runTask(@PathVariable long taskId){
        MigrationTask task = taskMapper.selectById(taskId);
        task.setStatus("初始化");
        task.setRunTime(0);
        taskMapper.updateById(task);
        template.convertAndSend("task-run", taskId+"");
        return new JSONResult();
    }

    @RequestMapping(value = "/task/migtables/{taskId}",method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public Response getMigrationTables(@PathVariable Long taskId){
        Response response = new Response();
        Page<MigrationTableStatus> page = getPage();
        IPage<MigrationTableStatus> pages = tableMapper.queryMigration(page, taskId);
        response.setTotal(pages.getTotal());
        response.setItems(pages.getRecords());
        return response;
    }

    @RequestMapping(value = "/task/masks/{taskId}",method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public Response getMaskList(@PathVariable long taskId){
        Response response = new Response();
        Page<MigrationTable> page = getPage();
        IPage<MigrationTable> pages = tableMapper.selectPage(page, new QueryWrapper<MigrationTable>().eq("task_id", taskId));
        response.setTotal(pages.getTotal());
        response.setItems(pages.getRecords());
        return response;
    }

    @RequestMapping(value = "/mask/create",method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public JSONResult createMask(@RequestBody MaskRequest request){
        Transformer transformer = request.convert(Transformer.class);
        try {
            JSONObject obj = new JSONObject();
            if(transformer.getName().equals("dx_replace")){
                obj.put("columnIndex", request.getColumnIndex());
                JSONArray arr = new JSONArray();
                arr.put(request.getStart());
                arr.put(request.getLength());
                arr.put(request.getChars());
                obj.put("paras",arr);
            }
            transformer.setParameter(obj.toString());
            transformerMapper.insert(transformer);
        }catch (Exception e){
            log.error(e.getMessage(), e);
            return new JSONResult("500", e.getMessage());
        }
        return new JSONResult();
    }

    @RequestMapping(value = "/task/columns",method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public JSONResult getColumns(long taskId, String tableName){
        List<String> columns = jobFileGenerator.getColumns(taskId, tableName);
        JSONResult<List<String>> result = new JSONResult<>();
        result.setData(columns);
        return result;
    }

}
